home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / Direct3D / VolumeTexture / volumetexture.cpp < prev    next >
C/C++ Source or Header  |  2001-10-31  |  12KB  |  361 lines

  1. //-----------------------------------------------------------------------------
  2. // File: VolumeTexture.cpp
  3. //
  4. // Desc: Example code showing how to do volume textures in D3D.
  5. //
  6. // Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include <D3DX8.h>
  12. #include "D3DApp.h"
  13. #include "D3DFile.h"
  14. #include "D3DFont.h"
  15. #include "D3DUtil.h"
  16. #include "DXUtil.h"
  17.  
  18.  
  19.  
  20.  
  21. //-----------------------------------------------------------------------------
  22. // Defines, constants, and global variables
  23. //-----------------------------------------------------------------------------
  24. struct VOLUMEVERTEX
  25. {
  26.     FLOAT      x, y, z;
  27.     DWORD      color;
  28.     FLOAT      tu, tv, tw;
  29. };
  30.  
  31. #define D3DFVF_VOLUMEVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1|D3DFVF_TEXCOORDSIZE3(0))
  32.  
  33. VOLUMEVERTEX g_vVertices[4] =
  34. {
  35.     { 1.0f, 1.0f, 0.0f, 0xffffffff, 1.0f, 1.0f, 0.0f },
  36.     {-1.0f, 1.0f, 0.0f, 0xffffffff, 0.0f, 1.0f, 0.0f },
  37.     { 1.0f,-1.0f, 0.0f, 0xffffffff, 1.0f, 0.0f, 0.0f },
  38.     {-1.0f,-1.0f, 0.0f, 0xffffffff, 0.0f, 0.0f, 0.0f }
  39. };
  40.  
  41.  
  42.  
  43.  
  44. //-----------------------------------------------------------------------------
  45. // Name: class CMyD3DApplication
  46. // Desc: Application class. The base class (CD3DApplication) provides the 
  47. //       generic functionality needed in all Direct3D samples. CMyD3DApplication 
  48. //       adds functionality specific to this sample program.
  49. //-----------------------------------------------------------------------------
  50. class CMyD3DApplication : public CD3DApplication
  51. {
  52.     CD3DFont* m_pFont;
  53.     LPDIRECT3DVOLUMETEXTURE8 m_pVolumeTexture;
  54.     LPDIRECT3DVERTEXBUFFER8  m_pVB;
  55.  
  56.     HRESULT ConfirmDevice( D3DCAPS8*, DWORD, D3DFORMAT );
  57.  
  58. protected:
  59.     HRESULT OneTimeSceneInit();
  60.     HRESULT InitDeviceObjects();
  61.     HRESULT RestoreDeviceObjects();
  62.     HRESULT InvalidateDeviceObjects();
  63.     HRESULT DeleteDeviceObjects();
  64.     HRESULT FinalCleanup();
  65.     HRESULT Render();
  66.     HRESULT FrameMove();
  67.  
  68. public:
  69.     CMyD3DApplication();
  70. };
  71.  
  72.  
  73.  
  74.  
  75. //-----------------------------------------------------------------------------
  76. // Name: WinMain()
  77. // Desc: Entry point to the program. Initializes everything, and goes into a
  78. //       message-processing loop. Idle time is used to render the scene.
  79. //-----------------------------------------------------------------------------
  80. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
  81. {
  82.     CMyD3DApplication d3dApp;
  83.  
  84.     if( FAILED( d3dApp.Create( hInst ) ) )
  85.         return 0;
  86.  
  87.     return d3dApp.Run();
  88. }
  89.  
  90.  
  91.  
  92.  
  93. //-----------------------------------------------------------------------------
  94. // Name: CMyD3DApplication()
  95. // Desc: Application constructor. Sets attributes for the app.
  96. //-----------------------------------------------------------------------------
  97. CMyD3DApplication::CMyD3DApplication()
  98. {
  99.     m_strWindowTitle    = _T("VolumeTexture");
  100.     m_bUseDepthBuffer   = TRUE;
  101.  
  102.     m_pFont          = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
  103.     m_pVolumeTexture = NULL;
  104.     m_pVB            = NULL;
  105. }
  106.  
  107.  
  108.  
  109.  
  110. //-----------------------------------------------------------------------------
  111. // Name: OneTimeSceneInit()
  112. // Desc: Called during initial app startup, this function performs all the
  113. //       permanent initialization.
  114. //-----------------------------------------------------------------------------
  115. HRESULT CMyD3DApplication::OneTimeSceneInit()
  116. {
  117.     return S_OK;
  118. }
  119.  
  120.  
  121.  
  122.  
  123. //-----------------------------------------------------------------------------
  124. // Name: FrameMove()
  125. // Desc: Called once per frame, the call is the entry point for animating
  126. //       the scene.
  127. //-----------------------------------------------------------------------------
  128. HRESULT CMyD3DApplication::FrameMove()
  129. {
  130.     static FLOAT fAngle = 0.0f;
  131.     fAngle += 0.1f;
  132.  
  133.     // Play with the volume texture coordinate
  134.     VOLUMEVERTEX* pVertices = NULL;
  135.     m_pVB->Lock( 0, 4*sizeof(VOLUMEVERTEX), (BYTE**)&pVertices, 0 );
  136.     for( int i=0; i<4; i++ )
  137.         pVertices[i].tw = sinf(fAngle)*sinf(fAngle);
  138.     m_pVB->Unlock();
  139.  
  140.     return S_OK;
  141. }
  142.  
  143.  
  144.  
  145.  
  146. //-----------------------------------------------------------------------------
  147. // Name: Render()
  148. // Desc: Called once per frame, the call is the entry point for 3d
  149. //       rendering. This function sets up render states, clears the
  150. //       viewport, and renders the scene.
  151. //-----------------------------------------------------------------------------
  152. HRESULT CMyD3DApplication::Render()
  153. {
  154.     // Clear the viewport
  155.     m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
  156.                          0x00000000, 1.0f, 0L );
  157.  
  158.     // Begin the scene
  159.     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
  160.     {
  161.         // Draw the quad, with the volume texture
  162.         m_pd3dDevice->SetTexture( 0, m_pVolumeTexture );
  163.         m_pd3dDevice->SetVertexShader( D3DFVF_VOLUMEVERTEX );
  164.         m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(VOLUMEVERTEX) );
  165.         m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);
  166.  
  167.         // Output statistics
  168.         m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
  169.         m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
  170.  
  171.         // End the scene.
  172.         m_pd3dDevice->EndScene();
  173.     }
  174.  
  175.     return S_OK;
  176. }
  177.  
  178.  
  179.  
  180.  
  181. //-----------------------------------------------------------------------------
  182. // Name: InitDeviceObjects()
  183. // Desc: Initialize scene objects.
  184. //-----------------------------------------------------------------------------
  185. HRESULT CMyD3DApplication::InitDeviceObjects()
  186. {
  187.     HRESULT hr;
  188.  
  189.     m_pFont->InitDeviceObjects( m_pd3dDevice );
  190.  
  191.     // Create a 64x64x4 volume texture
  192.     hr = m_pd3dDevice->CreateVolumeTexture( 16, 16, 16, 1, 0,
  193.                                             D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
  194.                                             &m_pVolumeTexture );
  195.     if( FAILED(hr) )
  196.         return hr;
  197.  
  198.     // Fill the volume texture
  199.     {
  200.         D3DLOCKED_BOX LockedBox;
  201.         hr = m_pVolumeTexture->LockBox( 0, &LockedBox, 0, 0 );
  202.         if( FAILED(hr) )
  203.             return hr;
  204.  
  205.         for( UINT w=0; w<16; w++ )
  206.         {
  207.             BYTE* pSliceStart = (BYTE*)LockedBox.pBits;
  208.  
  209.             for( UINT v=0; v<16; v++ )
  210.             {
  211.                 for( UINT u=0; u<16; u++ )
  212.                 {
  213.                     FLOAT du = (u-7.5f)/7.5f;
  214.                     FLOAT dv = (v-7.5f)/7.5f;
  215.                     FLOAT dw = (w-7.5f)/7.5f;
  216.                     FLOAT fScale = sqrtf( du*du + dv*dv + dw*dw ) / sqrtf(1.0f);
  217.  
  218.                     if( fScale > 1.0f ) fScale = 0.0f;
  219.                     else                fScale = 1.0f - fScale;
  220.  
  221.                                         DWORD r = (DWORD)((w<<4)*fScale);
  222.                                         DWORD g = (DWORD)((v<<4)*fScale);
  223.                                         DWORD b = (DWORD)((u<<4)*fScale);
  224.  
  225.                     ((DWORD*)LockedBox.pBits)[u] = 0xff000000 + (r<<16) + (g<<8) + (b);
  226.                 }
  227.                 LockedBox.pBits = (BYTE*)LockedBox.pBits + LockedBox.RowPitch;
  228.             }
  229.             LockedBox.pBits = pSliceStart + LockedBox.SlicePitch;
  230.         }
  231.  
  232.         m_pVolumeTexture->UnlockBox( 0 );
  233.     }
  234.  
  235.     // Create a vertex buffer
  236.     {
  237.         if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( 4*sizeof(VOLUMEVERTEX),
  238.                                            D3DUSAGE_WRITEONLY,
  239.                                            D3DFVF_VOLUMEVERTEX,
  240.                                            D3DPOOL_MANAGED, &m_pVB ) ) )
  241.             return hr;
  242.  
  243.         VOLUMEVERTEX* pVertices;
  244.         m_pVB->Lock( 0, 4*sizeof(VOLUMEVERTEX), (BYTE**)&pVertices, 0 );
  245.         memcpy( pVertices, g_vVertices, sizeof(VOLUMEVERTEX)*4 );
  246.         m_pVB->Unlock();
  247.     }
  248.  
  249.     return S_OK;
  250. }
  251.  
  252.  
  253.  
  254.  
  255. //-----------------------------------------------------------------------------
  256. // Name: RestoreDeviceObjects()
  257. // Desc: Initialize scene objects.
  258. //-----------------------------------------------------------------------------
  259. HRESULT CMyD3DApplication::RestoreDeviceObjects()
  260. {
  261.     m_pFont->RestoreDeviceObjects();
  262.  
  263.     // Set the matrices
  264.     D3DXVECTOR3 vEye( 0.0f, 0.0f,-3.0f );
  265.     D3DXVECTOR3 vAt(  0.0f, 0.0f, 0.0f );
  266.     D3DXVECTOR3 vUp(  0.0f, 1.0f, 0.0f );
  267.     D3DXMATRIX matWorld, matView, matProj;
  268.     D3DXMatrixIdentity( &matWorld );
  269.     D3DXMatrixLookAtLH( &matView, &vEye,&vAt, &vUp );
  270.     FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
  271.     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
  272.     m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
  273.     m_pd3dDevice->SetTransform( D3DTS_VIEW,       &matView );
  274.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  275.  
  276.     // Set state
  277.     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, FALSE );
  278.     m_pd3dDevice->SetRenderState( D3DRS_CLIPPING,     FALSE );
  279.     m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,     D3DCULL_NONE );
  280.     m_pd3dDevice->SetRenderState( D3DRS_CLIPPING,     FALSE );
  281.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING,     FALSE );
  282.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,      FALSE );
  283.     m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
  284.  
  285.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
  286.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  287.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  288.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
  289.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  290.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
  291.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  292.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  293.  
  294.     return S_OK;
  295. }
  296.  
  297.  
  298.  
  299.  
  300. //-----------------------------------------------------------------------------
  301. // Name: InvalidateDeviceObjects()
  302. // Desc:
  303. //-----------------------------------------------------------------------------
  304. HRESULT CMyD3DApplication::InvalidateDeviceObjects()
  305. {
  306.     m_pFont->InvalidateDeviceObjects();
  307.     return S_OK;
  308. }
  309.  
  310.  
  311.  
  312.  
  313. //-----------------------------------------------------------------------------
  314. // Name: DeleteDeviceObjects()
  315. // Desc: Called when the app is exiting, or the device is being changed,
  316. //       this function deletes any device dependent objects.
  317. //-----------------------------------------------------------------------------
  318. HRESULT CMyD3DApplication::DeleteDeviceObjects()
  319. {
  320.     m_pFont->DeleteDeviceObjects();
  321.     SAFE_RELEASE( m_pVolumeTexture );
  322.     SAFE_RELEASE( m_pVB );
  323.  
  324.     return S_OK;
  325. }
  326.  
  327.  
  328.  
  329.  
  330. //-----------------------------------------------------------------------------
  331. // Name: FinalCleanup()
  332. // Desc: Called before the app exits, this function gives the app the chance
  333. //       to cleanup after itself.
  334. //-----------------------------------------------------------------------------
  335. HRESULT CMyD3DApplication::FinalCleanup()
  336. {
  337.     SAFE_DELETE( m_pFont );
  338.     return S_OK;
  339. }
  340.  
  341.  
  342.  
  343.  
  344. //-----------------------------------------------------------------------------
  345. // Name: ConfirmDevice()
  346. // Desc: Called during device intialization, this code checks the device
  347. //       for some minimum set of capabilities
  348. //-----------------------------------------------------------------------------
  349. HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior,
  350.                                           D3DFORMAT Format )
  351. {
  352.     if( 0 == ( pCaps->TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP ) )
  353.         return E_FAIL;
  354.  
  355.     return S_OK;
  356. }
  357.  
  358.  
  359.  
  360.  
  361.